package com.dog.basics.netty.server;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import com.dog.basics.bean.model.mtkj.MtDeviceLock;
import com.dog.basics.netty.init.SocketChannelInitializer;
import com.dog.basics.netty.util.SessionSocketHolder;
import com.dog.basics.service.mtkj.IMtDeviceLockService;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.util.ResourceLeakDetector;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import java.net.InetSocketAddress;
import java.util.List;

/**
 * Function: tcp启动配置信息
 *
 * @author guonh
 * Date: 21/05/2018 00:30
 * @since JDK 1.8
 */
@Component
@Log4j2
@Order(180)
public class CIMServer {

    private EventLoopGroup boss = new NioEventLoopGroup();
    private EventLoopGroup work = new NioEventLoopGroup();


    @Value("${survey.server.port}")
    private int nettyPort;

    @Resource
    private IMtDeviceLockService deviceLockService;

    /**
     * 启动 cim server
     *
     * @return
     * @throws InterruptedException
     */
    @PostConstruct
    public void start() throws InterruptedException {
        ServerBootstrap bootstrap = new ServerBootstrap()
                .group(boss, work)
                .channel(NioServerSocketChannel.class)
                .localAddress(new InetSocketAddress(nettyPort))
                //保持长连接
                .childOption(ChannelOption.SO_KEEPALIVE, true)
                .childHandler(new SocketChannelInitializer());
        //内存泄漏检测 开发推荐PARANOID 线上SIMPLE
        ResourceLeakDetector.setLevel(ResourceLeakDetector.Level.SIMPLE);
        ChannelFuture future = bootstrap.bind().sync();
        if (future.isSuccess()) {
            log.info("启动 Dog - 商务机 一号Server 成功");
        }
    }


    /**
     * 销毁 - 并且下线
     */
    @PreDestroy
    public void destroy() {
        // 获取在线设备一一下线
        List<MtDeviceLock> devices = CollUtil.newArrayList();
        // 数据循环处理 - 组装修改下线的设备信息
        SessionSocketHolder.getMap().keySet().forEach(e -> {
            MtDeviceLock deviceLock = new MtDeviceLock();
            deviceLock.setId(e);
            deviceLock.setDevOnlineState(0);
            deviceLock.setUpdateTime(DateUtil.currentSeconds());
            devices.add(deviceLock);
        });
        // 组装好数据信息 - 判断是否为空 - 不为空则批量修改数据信息
        if (CollUtil.isNotEmpty(devices)) {
            // 关闭neety服务 设备下线
            deviceLockService.updateBatchById(devices);
            // 打印下线
            log.info("设备下线数量:" + devices.size());
        }

        boss.shutdownGracefully().syncUninterruptibly();
        work.shutdownGracefully().syncUninterruptibly();
        log.info("关闭 cim server 成功");
    }

}

